#ifndef TWI_H_INCLUDED
#define TWI_H_INCLUDED
#include "leaf/base.h"
#include <leaf/osiface.h>

#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <lib_bupt/usart.h>"
# define F_CPU 14745600UL
#endif
#define TWBR_FROM_FREQ( f ) ( (F_CPU/(f) - 16 + 1<<( (uint16_t)(TWSR&0x03) << 1 )) / 1 )

/* (mode & TWI_TR_MASK) 0-T, 1-R */
#define TWI_TR_MASK 0x01
/* (mode & TWI_MS_MASK) 0-M, 1-S */
#define TWI_MS_MASK 0x02
typedef enum{
	TwiModeStop = 0,
	TwiModeST   = 2,
	TwiModeSR   = 3,
	TwiModeMT   = 4,
	TwiModeMR   = 5
}TwiMode;
typedef enum{
	TwiErrOpen  = -1,
	TwiErrStart = -2,
	TwiErrSla   = -3,
	TwiErrMatch = -4,
	TwiErrOther = -6
}TwiErrState;

typedef uint8_t TwiStatus;
typedef uint8_t TwiAddr;

typedef struct{
	TwiMode mode;
	TwiAddr target;
	TwiStatus status;
	union{
		void *r;
		const void *w;
	}buf;
	size_t cnt;
	TimerMessageBlock msg;
	Bool timeout;
	MessageQueue q;
	Mutex lock;
}Twi;

/* 初始化设备，指定波特率（分频为00） */
void twi_init( uint8_t baud, TwiAddr addr );
int  twi_write( TwiAddr sla, const void *data, size_t sz );
int  twi_read( void *buf, size_t sz);
void twi_set_timeout( unsigned to ); //twiSetTimeout( 0 )可以取消twi的超时设置
inline TwiStatus twi_get_status( void );
#endif
